<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
<canvas id="physics-canvas" width="550" height="420"></canvas>
<script>
    const canvas = document.getElementById('physics-canvas');
    const ctx = canvas.getContext('2d');

    // Style
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2;
    ctx.font = '20px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // --- Draw Ground ---
    ctx.beginPath();
    ctx.moveTo(30, 380);
    ctx.lineTo(520, 380);
    ctx.stroke();
    // Shaded ground area
    ctx.save();
    ctx.lineWidth = 1;
    ctx.strokeStyle = '#cccccc';
    for (let i = 0; i < 15; i++) {
        ctx.beginPath();
        ctx.moveTo(30 + i * 10, 382);
        ctx.lineTo(30 + 490 - i * 10, 382);
    }
    // simple fill as in original
    ctx.fillStyle = '#f0f0f0';
    ctx.fillRect(30, 381, 490, 15);
    ctx.stroke();
    ctx.restore();


    // --- Draw Frame ---
    // Right Post
    ctx.beginPath();
    ctx.moveTo(480, 100);
    ctx.lineTo(480, 380);
    ctx.stroke();

    // Horizontal Bar
    ctx.beginPath();
    ctx.moveTo(150, 150);
    ctx.lineTo(480, 150);
    ctx.stroke();
    
    // Left Post
    ctx.beginPath();
    ctx.moveTo(150, 150);
    ctx.lineTo(150, 380);
    ctx.stroke();

    // Pulley Support (Fork/Pointed structure)
    const pulleyCenter = { x: 120, y: 120 };
    ctx.beginPath();
    ctx.moveTo(150, 150);
    ctx.lineTo(pulleyCenter.x, pulleyCenter.y);
    ctx.stroke();
    // The image shows the support is a single pointed piece from the frame corner
    // This is a good representation of that.
    ctx.beginPath();
    ctx.moveTo(150, 170); // Point on the left post below the corner
    ctx.lineTo(pulleyCenter.x, pulleyCenter.y);
    ctx.stroke();


    // --- Draw Pulley ---
    const pulleyRadius = 30;
    ctx.beginPath();
    ctx.arc(pulleyCenter.x, pulleyCenter.y, pulleyRadius, 0, 2 * Math.PI);
    ctx.stroke();
    
    // Draw axle dot
    ctx.beginPath();
    ctx.arc(pulleyCenter.x, pulleyCenter.y, 2, 0, 2 * Math.PI);
    ctx.fillStyle = 'black';
    ctx.fill();


    // --- Draw Spring ---
    // The diagram simplifies the connection, showing the spring pulling horizontally from the axle level.
    const springY = pulleyCenter.y;
    // A small piece of string connects the pulley to the spring
    const stringToSpringStart = { x: pulleyCenter.x + pulleyRadius, y: springY };
    const springStartX = stringToSpringStart.x + 5;
    ctx.beginPath();
    ctx.moveTo(stringToSpringStart.x, stringToSpringStart.y);
    ctx.lineTo(springStartX, springY);
    ctx.stroke();
    
    // Spring itself
    const springEndX = 480;
    const springAmplitude = 12;
    const coils = 10;
    const springLength = springEndX - springStartX;
    const segmentLength = springLength / coils;

    ctx.beginPath();
    ctx.moveTo(springStartX, springY);
    // Trace the top edge of the spring
    for (let i = 0; i < coils; i++) {
        const startSegX = springStartX + i * segmentLength;
        ctx.lineTo(startSegX + segmentLength / 2, springY - springAmplitude);
        ctx.lineTo(startSegX + segmentLength, springY);
    }
    // Trace the bottom edge of the spring in reverse
    for (let i = coils - 1; i >= 0; i--) {
        const startSegX = springStartX + i * segmentLength;
        ctx.lineTo(startSegX + segmentLength / 2, springY + springAmplitude);
        ctx.lineTo(startSegX, springY);
    }
    ctx.closePath();
    ctx.fillStyle = '#e8e8e8'; // Light gray fill to mimic the look
    ctx.fill();
    ctx.stroke(); // Black outline for the spring


    // --- Draw Hanging String and Mass ---
    const stringTop = { x: pulleyCenter.x - pulleyRadius, y: pulleyCenter.y };
    const stringBottomY = 250;
    ctx.beginPath();
    ctx.moveTo(stringTop.x, stringTop.y);
    ctx.lineTo(stringTop.x, stringBottomY); // String stops at the top of the mass
    ctx.stroke();

    const mass = { w: 50, h: 40 };
    ctx.fillStyle = '#f9f9f9'; // Fill for the mass block
    ctx.fillRect(stringTop.x - mass.w / 2, stringBottomY, mass.w, mass.h);
    ctx.strokeRect(stringTop.x - mass.w / 2, stringBottomY, mass.w, mass.h);

    // --- Draw Labels ---
    // Radius 'r'
    ctx.beginPath();
    ctx.moveTo(pulleyCenter.x, pulleyCenter.y);
    ctx.lineTo(pulleyCenter.x - pulleyRadius, pulleyCenter.y);
    ctx.stroke();
    
    // Small arc to indicate radius
    ctx.beginPath();
    ctx.arc(pulleyCenter.x, pulleyCenter.y, pulleyRadius * 0.5, Math.PI, Math.PI * 1.3);
    ctx.stroke();
    
    ctx.fillStyle = 'black';
    ctx.font = 'italic 20px Arial';
    ctx.fillText('r', pulleyCenter.x - pulleyRadius * 0.6, pulleyCenter.y - 12);

    // --- Draw Caption ---
    ctx.font = '24px KaiTi'; // Use a font that supports Chinese characters
    ctx.fillText('习题 3-12 图', 275, 405);

</script>
</body>
</html>